Skip to content

Node.js joi使用

我们用nodejs实现一些功能时,往往需要对用户输入的数据进行验证。然而,验证是一件麻烦的事情,很有可能你需要验证数据类型,长度,特定规则等等,在前端做表单验证时,我们常用的做法是使用正则,正则表达式也许可以一步到位,但是他只会给你true or false,如果想要知道数据不符合哪些条件时,那么你要进一步判断,下面和大家分享一种可读性和易用性更好的实现方法。

Joi 是 hapijs 自带的数据校验模块,他已经高度封装常用的校验功能,本文就是介绍如何优雅地使用 joi 对数据进行校验。相信你会喜欢上他。便于大家理解,以登录为例,一般分两种方式:A或B (输入密码或二维码),那么 joi 的配置如下即可实现检验:

var Joi = require('joi');
var schema = Joi.object({
    username: Joi.string().min(3).max(30).required(),
    isA: Joi.boolean(),
    AVal: Joi.number(),
    isB: Joi.boolean(),
    BVal: Joi.string()
})
.with('isA', 'AVal')
.with('isB', 'BVal')
.without('isA', 'isB')
.or('isA', 'isB');

以上scheme配置大致意思如下:

  • username: 字符串类型,长度在3至30之间,必填。

  • isA: 布尔类型,可选

  • AVal: 数字类型, 可选

  • isB: 布尔类型, 可选

  • BVal: 字符串类型, 可选

  • with('isA', 'AVal') //意思是,isA 和 AVal 这两字段如果填写了isA,也必须要填写AVal

  • with('isB', 'BVal') //道理同上

  • without('isA', 'isB'); //意思是 isA 和 isB 只能填写其中一个

  • or('isA', 'isB') //意思是 isA 和 isB 这两字段至少填写其一

Nodejs中的使用

在我们的Nodejs项目中,我们就把joi写成了一个中间件进行使用

看看我们的authControllerPolicy.js, 这个就是我们写的中间件,joi具体的格式的规定我们可以去他的文档里查看

const Joi = require('joi')

module.exports = {
  register (req, res, next) {
    console.log(req.body)
    const schema = {
      username: Joi.string(),
      email: Joi.string().email(),
      password: Joi.string().regex(
        new RegExp('^.{8,32}$')
      ),
      phone: Joi.string().length(11)
    }

    const { error } = Joi.validate(req.body, schema)

    if (error) {
      console.log(error)
      switch (error.details[0].context.key) {
        case 'username':
          res.status(400).send({
            error: 'A valid username should be provided!'
          })
          break
        case 'email':
          res.status(400).send({
            error: 'A valid email should be provided!'
          })
          break
        case 'password':
          res.status(400).send({
            error: 'The length of password should be 8-32!'
          })
          break
        case 'phone':
          res.status(400).send({
            error: 'A valid phoneNum should be provided!'
          })
          break
        default:
          res.status(400).send({
            error: 'Invalid registration information!'
          })
      }
    } else {
      next()
    }
  }
}

完成了这个中间件后,使用就十分方便了, 使用的方式如下

app.post('/user', 
    authControllerPolicy.register,
    authController.register)

这样使用中间件的方式十分方便,大家有需要可以参考